{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Basic Gates Kata\n",
    "\n",
    "**Basic Gates** quantum kata is a series of exercises designed\n",
    "to get you familiar with the basic quantum gates in Q#.\n",
    "It covers the following topics:\n",
    "* basic single-qubit and multi-qubit gates,\n",
    "* adjoint and controlled gates,\n",
    "* using gates to modify the state of a qubit.\n",
    "\n",
    "Each task is wrapped in one operation preceded by the description of the task.\n",
    "Your goal is to fill in the blank (marked with `// ...` comments)\n",
    "with some Q# code that solves the task. To verify your answer, run the cell using Ctrl+Enter (⌘+Enter on macOS).\n",
    "\n",
    "Most tasks in this kata can be done using exactly one gate.\n",
    "None of the tasks require measurement, and the tests are written so as to fail if qubit state is measured.\n",
    "\n",
    "The tasks are given in approximate order of increasing difficulty; harder ones are marked with asterisks."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In all tasks you need to implement the transformation exactly, without introducing any global phase. You can read more about the global phase of quantum states [here](../tutorials/Qubit/Qubit.ipynb#Relative-and-Global-Phase)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part I. Single-Qubit Gates\n",
    "\n",
    "### Theory\n",
    "\n",
    "* [The qubit (tutorial)](./../tutorials/Qubit/Qubit.ipynb) introduces single-qubit systems and their states.\n",
    "* [Single-qubit gates (tutorial)](./../tutorials/SingleQubitGates/SingleQubitGates.ipynb) covers single-qubit gates.\n",
    "* [Multi-qubit systems (tutorial)](./../tutorials/MultiQubitSystems/MultiQubitSystems.ipynb) introduces multi-qubit systems (tasks 1.8-1.10).\n",
    "* [Quirk](http://algassert.com/quirk) is a convenient tool for visualizing the effect of gates on qubit states.\n",
    "\n",
    "### Q# materials\n",
    "\n",
    "* Basic gates provided in Q# belong to the `Microsoft.Quantum.Intrinsic` namespace and are listed [here](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic).\n",
    "\n",
    "> Note that all operations in this section have `is Adj+Ctl` in their signature.\n",
    "This means that they should be implemented in a way that allows Q# \n",
    "to compute their adjoint and controlled variants automatically.\n",
    "Since each task is solved using only intrinsic gates, you should not need to put any special effort in this."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 1.1. State flip: $|0\\rangle$ to $|1\\rangle$ and vice versa\n",
    "\n",
    "**Input:** A qubit in state $|\\psi\\rangle = \\alpha |0\\rangle + \\beta |1\\rangle$.\n",
    "\n",
    "**Goal:**  Change the state of the qubit to $\\alpha |1\\rangle + \\beta |0\\rangle$.\n",
    "\n",
    "**Example:**\n",
    "\n",
    "If the qubit is in state $|0\\rangle$, change its state to $|1\\rangle$.\n",
    "\n",
    "If the qubit is in state $|1\\rangle$, change its state to $|0\\rangle$.\n",
    "\n",
    "> Note that this operation is self-adjoint: applying it for a second time\n",
    "> returns the qubit to the original state. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T101_StateFlip \n",
    "\n",
    "operation StateFlip (q : Qubit) : Unit is Adj+Ctl {\n",
    "    // The Pauli X gate will change the |0⟩ state to the |1⟩ state and vice versa.\n",
    "    // Type X(q);\n",
    "    // Then run the cell using Ctrl+Enter (⌘+Enter on macOS).\n",
    "\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-1.1.-State-flip:-$|0\\rangle$-to-$|1\\rangle$-and-vice-versa).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 1.2. Basis change: $|0\\rangle$ to $|+\\rangle$ and $|1\\rangle$ to $|-\\rangle$ (and vice versa)\n",
    "\n",
    "**Input**: A qubit in state $|\\psi\\rangle = \\alpha |0\\rangle + \\beta |1\\rangle$.\n",
    "\n",
    "**Goal**:  Change the state of the qubit as follows:\n",
    "* If the qubit is in state $|0\\rangle$, change its state to $|+\\rangle = \\frac{1}{\\sqrt{2}} \\big(|0\\rangle + |1\\rangle\\big)$.\n",
    "* If the qubit is in state $|1\\rangle$, change its state to $|-\\rangle = \\frac{1}{\\sqrt{2}} \\big(|0\\rangle - |1\\rangle\\big)$.\n",
    "* If the qubit is in superposition, change its state according to the effect on basis vectors.\n",
    "\n",
    "> Note:  \n",
    "> $|+\\rangle$ and $|-\\rangle$ form a different basis for single-qubit states, called X basis.  \n",
    "> $|0\\rangle$ and $|1\\rangle$ are called Z basis.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T102_BasisChange \n",
    "\n",
    "operation BasisChange (q : Qubit) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-1.2.-Basis-change:-$|0\\rangle$-to-$|+\\rangle$-and-$|1\\rangle$-to-$|-\\rangle$-(and-vice-versa)).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 1.3. Sign flip: $|+\\rangle$  to $|-\\rangle$  and vice versa.\n",
    "\n",
    "**Input**: A qubit in state $|\\psi\\rangle = \\alpha |0\\rangle + \\beta |1\\rangle$.\n",
    "\n",
    "**Goal** :  Change the qubit state to $\\alpha |0\\rangle - \\beta |1\\rangle$ (flip the sign of $|1\\rangle$ component of the superposition).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T103_SignFlip \n",
    "\n",
    "operation SignFlip (q : Qubit) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-1.3.-Sign-flip:-$|+\\rangle$--to-$|-\\rangle$--and-vice-versa.).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 1.4. Amplitude change: $|0\\rangle$ to $\\cos{α} |0\\rangle + \\sin{α} |1\\rangle$.\n",
    "\n",
    "**Inputs:**\n",
    "\n",
    "1. Angle α, in radians, represented as Double.\n",
    "2. A qubit in state $|\\psi\\rangle = \\beta |0\\rangle + \\gamma |1\\rangle$.\n",
    "\n",
    "**Goal:**  Change the state of the qubit as follows:\n",
    "- If the qubit is in state $|0\\rangle$, change its state to $\\cos{α} |0\\rangle + \\sin{α} |1\\rangle$.\n",
    "- If the qubit is in state $|1\\rangle$, change its state to $-\\sin{α} |0\\rangle + \\cos{α} |1\\rangle$.\n",
    "- If the qubit is in superposition, change its state according to the effect on basis vectors.\n",
    "\n",
    "> This is the first operation in this kata that is not self-adjoint, i.e., applying it for a second time\n",
    "> does not return the qubit to the original state."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T104_AmplitudeChange\n",
    "\n",
    "operation AmplitudeChange (alpha : Double, q : Qubit) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-1.4.-Amplitude-change:-$|0\\rangle$-to-$\\cos{α}-|0\\rangle-+-\\sin{α}-|1\\rangle$.).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 1.5. Phase flip\n",
    "\n",
    "**Input:** A qubit in state $|\\psi\\rangle = \\alpha |0\\rangle + \\beta |1\\rangle$.\n",
    "\n",
    "**Goal:** Change the qubit state to $\\alpha |0\\rangle + {\\color{red}i}\\beta |1\\rangle$ (add a relative phase $i$ to $|1\\rangle$ component of the superposition).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T105_PhaseFlip\n",
    "\n",
    "operation PhaseFlip (q : Qubit) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-1.5.-Phase-flip).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 1.6. Phase change\n",
    "\n",
    "**Inputs:**\n",
    "\n",
    "1. Angle α, in radians, represented as Double.\n",
    "2. A qubit in state $|\\psi\\rangle = \\beta |0\\rangle + \\gamma |1\\rangle$.\n",
    "\n",
    "**Goal:**  Change the state of the qubit as follows:\n",
    "- If the qubit is in state $|0\\rangle$, don't change its state.\n",
    "- If the qubit is in state $|1\\rangle$, change its state to $e^{i\\alpha} |1\\rangle$.\n",
    "- If the qubit is in superposition, change its state according to the effect on basis vectors: $\\beta |0\\rangle + {\\color{red}{e^{i\\alpha}}} \\gamma |1\\rangle$.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T106_PhaseChange\n",
    "\n",
    "operation PhaseChange (alpha : Double, q : Qubit) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-1.6.-Phase-change).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 1.7. Global phase change\n",
    "**Input:** A qubit in state $|\\psi\\rangle = \\beta |0\\rangle + \\gamma |1\\rangle$.\n",
    "\n",
    "**Goal**: Change the state of the qubit to $- \\beta |0\\rangle - \\gamma |1\\rangle$.\n",
    "\n",
    "> Note: this change on its own is not observable - there is no experiment you can do on a standalone qubit to figure out whether it acquired the global phase or not. \n",
    "> However, you can use a controlled version of this operation to observe the global phase it introduces. \n",
    "> This is used in later katas as part of more complicated tasks.\n",
    "\n",
    "<details>\n",
    "  <summary><b>Need a hint? Click here</b></summary>\n",
    "  Can you apply one of the rotation gates? Take a look at the functions in the Microsoft.Quantum.Math package to use a common mathematical constant and remember to import the package using the open directive.    \n",
    "</details>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T107_GlobalPhaseChange\n",
    "\n",
    "operation GlobalPhaseChange (q : Qubit) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-1.7.-Global-phase-change).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> The next three tasks deal with multi-qubit systems, though they still only require single-qubit gates.\n",
    "> We recommend going through the [MultiQubitSystems tutorial](./../tutorials/MultiQubitSystems/MultiQubitSystems.ipynb) before attempting these.\n",
    "\n",
    "### Task 1.8. Bell state change - 1\n",
    "\n",
    "**Input:** Two entangled qubits in Bell state $|\\Phi^{+}\\rangle = \\frac{1}{\\sqrt{2}} \\big(|00\\rangle + |11\\rangle\\big)$.\n",
    "\n",
    "**Goal:**  Change the two-qubit state to $|\\Phi^{-}\\rangle = \\frac{1}{\\sqrt{2}} \\big(|00\\rangle - |11\\rangle\\big)$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T108_BellStateChange1\n",
    "\n",
    "operation BellStateChange1 (qs : Qubit[]) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-1.8.-Bell-state-change---1).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 1.9. Bell state change - 2\n",
    "\n",
    "**Input:** Two entangled qubits in Bell state $|\\Phi^{+}\\rangle = \\frac{1}{\\sqrt{2}} \\big(|00\\rangle + |11\\rangle\\big)$.\n",
    "\n",
    "**Goal:**  Change the two-qubit state to $|\\Psi^{+}\\rangle = \\frac{1}{\\sqrt{2}} \\big(|01\\rangle + |10\\rangle\\big)$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T109_BellStateChange2\n",
    "\n",
    "operation BellStateChange2 (qs : Qubit[]) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-1.9.-Bell-state-change---2).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 1.10. Bell state change - 3\n",
    "\n",
    "**Input:** Two entangled qubits in Bell state $|\\Phi^{+}\\rangle = \\frac{1}{\\sqrt{2}} \\big(|00\\rangle + |11\\rangle\\big)$.\n",
    "\n",
    "**Goal:**  Change the two-qubit state, without adding a global phase, to $|\\Psi^{-}\\rangle = \\frac{1}{\\sqrt{2}} \\big(|01\\rangle - |10\\rangle\\big)$.\n",
    "\n",
    "<details>\n",
    "    <summary><b>Need a hint? Click here</b></summary>\n",
    "A similar transformation could be done using a single <b>Y</b> gate on the first qubit. However the <b>Y</b> gate also adds a global phase (more on that can be found <a href=\"../tutorials/Qubit/Qubit.ipynb#Relative-and-Global-Phase\">here</a>) which is not intended in this exercise.  \n",
    "\n",
    "Look for a solution, possibly with multiple gates, which has a very similar transformation as the <b>Y</b> gate but without adding a global phase.    \n",
    "</details>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T110_BellStateChange3\n",
    "\n",
    "operation BellStateChange3 (qs : Qubit[]) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-1.10.-Bell-state-change---3).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part II. Multi-Qubit Gates\n",
    "\n",
    "> In the following tasks the order of qubit states in task description matches the order of qubits in the array (i.e., $|10\\rangle$ state corresponds to `qs[0]` in state $|1\\rangle$ and `qs[1]` in state $|0\\rangle$).\n",
    "> \n",
    "> Note also that the states shown in test output use little-endian notation (similarly to `DumpMachine`), see this [tutorial section](../tutorials/MultiQubitSystems/MultiQubitSystems.ipynb#Endianness) for a refresher on endianness.\n",
    "\n",
    "### Theory\n",
    "\n",
    "* [Multi-qubit gates (tutorial)](./../tutorials/MultiQubitGates/MultiQubitGates.ipynb) covers multi-qubit gates.\n",
    "\n",
    "### Q# materials\n",
    "\n",
    "* Using controlled and adjoint versions of gates is covered in the Q# documentation on [operations](https://docs.microsoft.com/azure/quantum/user-guide/language/expressions/functorapplication)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 2.1. Two-qubit gate - 1\n",
    "\n",
    "**Input:** Two unentangled qubits (stored in an array of length 2).\n",
    "The first qubit will be in state $|\\psi\\rangle = \\alpha |0\\rangle + \\beta |1\\rangle$, the second - in state $|0\\rangle$\n",
    "(this can be written as two-qubit state  $\\big(\\alpha |0\\rangle + \\beta |1\\rangle \\big) \\otimes |0\\rangle = \\alpha |00\\rangle + \\beta |10\\rangle$.\n",
    "\n",
    "\n",
    "**Goal:**  Change the two-qubit state to $\\alpha |00\\rangle + \\beta |11\\rangle$.\n",
    "\n",
    "> Note that unless the starting state of the first qubit was $|0\\rangle$ or $|1\\rangle$,\n",
    "> the resulting two-qubit state can not be represented as a tensor product\n",
    "> of the states of individual qubits any longer; thus the qubits become entangled."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T201_TwoQubitGate1\n",
    "\n",
    "operation TwoQubitGate1 (qs : Qubit[]) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-2.1.-Two-qubit-gate---1).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 2.2. Two-qubit gate - 2\n",
    "\n",
    "**Input:** Two unentangled qubits (stored in an array of length 2) in state $|+\\rangle \\otimes |+\\rangle = \\frac{1}{2} \\big( |00\\rangle + |01\\rangle + |10\\rangle {\\color{blue}+} |11\\rangle \\big)$.\n",
    "\n",
    "\n",
    "**Goal:**  Change the two-qubit state to $\\frac{1}{2} \\big( |00\\rangle + |01\\rangle + |10\\rangle {\\color{red}-} |11\\rangle \\big)$.\n",
    "\n",
    "> Note that while the starting state can be represented as a tensor product of single-qubit states,\n",
    "> the resulting two-qubit state can not be represented in such a way."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T202_TwoQubitGate2\n",
    "\n",
    "operation TwoQubitGate2 (qs : Qubit[]) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-2.2.-Two-qubit-gate---2).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 2.3. Two-qubit gate - 3\n",
    "\n",
    "**Input:** Two qubits (stored in an array of length 2) in an arbitrary two-qubit state $\\alpha |00\\rangle + {\\color{blue}\\beta} |01\\rangle + {\\color{blue}\\gamma} |10\\rangle + \\delta |11\\rangle$.\n",
    "\n",
    "\n",
    "**Goal:**  Change the two-qubit state to $\\alpha |00\\rangle + {\\color{red}\\gamma} |01\\rangle + {\\color{red}\\beta} |10\\rangle + \\delta |11\\rangle$.\n",
    "\n",
    "> This task can be solved using one intrinsic gate; as an exercise, try to express the solution using several (possibly controlled) Pauli gates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T203_TwoQubitGate3\n",
    "\n",
    "operation TwoQubitGate3 (qs : Qubit[]) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-2.3.-Two-qubit-gate---3).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 2.4. Two-qubit gate - 4\n",
    "\n",
    "**Input:** Two qubits (stored in an array of length 2) in an arbitrary two-qubit state ${\\color{blue}\\alpha} |00\\rangle + {\\color{blue}\\beta} |01\\rangle + \\gamma |10\\rangle + \\delta |11\\rangle$.\n",
    "\n",
    "\n",
    "**Goal:**  Change the two-qubit state to ${\\color{red}\\beta} |00\\rangle + {\\color{red}\\alpha} |01\\rangle + \\gamma |10\\rangle + \\delta |11\\rangle$.\n",
    "\n",
    "> This task can be solved using one library function; as an exercise, try to express the solution using several (possibly controlled) Pauli gates.  \n",
    "\n",
    "> [ControlledOnInt function](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.canon.controlledonint) generates a controlled variant of the given gate, which is applied when the control register is in a state corresponding to a non-negative integer. For example,\n",
    "  * `ControlledOnInt(0, H)([qs[0]], qs[1])` applies the Hadamard gate to the `qs[1]` qubit when the control qubit `qs[0]` is in the $|0\\rangle$ state.  \n",
    "  * `ControlledOnInt(1, X)([qs[0]], qs[1])` applies the X gate to the `qs[1]` qubit when the control qubit `qs[0]` is in the $|1\\rangle$ state (equivalent to `CNOT(qs[0], qs[1])`).\n",
    ">\n",
    "> Notice that the `ControlledOnInt` function requires the control qubit(s) to be passed as an array. This function generates a gate controlled by multiple qubits. The argument gate is applied if the control register is in the basis state corresponding to the specified non-negative integer. The little-endian binary representation of this integer defines a bit mask, which is compared with the control register.\n",
    ">\n",
    "> A similar function `ControlledOnBitString` is introduced in the [Multi-Qubit Gates tutorial](../tutorials/MultiQubitGates/MultiQubitGates.ipynb#Other-Types-of-Controlled-Gates)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T204_TwoQubitGate4\n",
    "\n",
    "operation TwoQubitGate4 (qs : Qubit[]) : Unit is Adj+Ctl {\n",
    "    // ... \n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-2.4.-Two-qubit-gate---4).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 2.5. Toffoli gate\n",
    "\n",
    "**Input:** Three qubits (stored in an array of length 3) in an arbitrary three-qubit state \n",
    "$\\alpha |000\\rangle + \\beta |001\\rangle + \\gamma |010\\rangle + \\delta |011\\rangle + \\epsilon |100\\rangle + \\zeta|101\\rangle + {\\color{blue}\\eta}|110\\rangle + {\\color{blue}\\theta}|111\\rangle$.\n",
    "\n",
    "**Goal:** Flip the state of the third qubit if the state of the first two is $|11\\rangle$, i.e., change the three-qubit state to $\\alpha |000\\rangle + \\beta |001\\rangle + \\gamma |010\\rangle + \\delta |011\\rangle + \\epsilon |100\\rangle + \\zeta|101\\rangle + {\\color{red}\\theta}|110\\rangle + {\\color{red}\\eta}|111\\rangle$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T205_ToffoliGate\n",
    "\n",
    "operation ToffoliGate (qs : Qubit[]) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-2.5.-Toffoli-gate).*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 2.6. Fredkin gate\n",
    "\n",
    "**Input:** Three qubits (stored in an array of length 3) in an arbitrary three-qubit state \n",
    "$\\alpha |000\\rangle + \\beta |001\\rangle + \\gamma |010\\rangle + \\delta |011\\rangle + \\epsilon |100\\rangle + {\\color{blue}\\zeta}|101\\rangle + {\\color{blue}\\eta}|110\\rangle + \\theta|111\\rangle$.\n",
    "\n",
    "**Goal:** Swap the states of second and third qubit if and only if the state of the first qubit is $|1\\rangle$, i.e., change the three-qubit state to $\\alpha |000\\rangle + \\beta |001\\rangle + \\gamma |010\\rangle + \\delta |011\\rangle + \\epsilon |100\\rangle + {\\color{red}\\eta}|101\\rangle + {\\color{red}\\zeta}|110\\rangle + \\theta|111\\rangle$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T206_FredkinGate\n",
    "\n",
    "operation FredkinGate (qs : Qubit[]) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Can't come up with a solution? See the explained solution in the [Basic Gates Workbook](./Workbook_BasicGates.ipynb#Task-2.6.-Fredkin-gate).*"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Q#",
   "language": "qsharp",
   "name": "iqsharp"
  },
  "language_info": {
   "file_extension": ".qs",
   "mimetype": "text/x-qsharp",
   "name": "qsharp",
   "version": "0.24"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
